/*
 * @Author: xiaosihan 
 * @Date: 2024-01-20 03:47:37 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-03-10 19:28:13
 */

import { Group, Mesh, MeshBasicMaterial, MeshStandardMaterial, Vector3, Euler } from "three";
import adPNG from "./ad.png";
import OneFloor from "../OneFloor/OneFloor";
import FloorGroup from "./FloorGroup/FloorGroup";
import keyContorls from "three-base/keyContorls";
import { get, round } from "lodash";
import homeStore from "@views/home/homeStore";
import { autorun } from "mobx";
import threeLoader from "three-base/threeLoader";
import threeUtils from "three-base/threeUtils";
import MeshBase from "../MeshBase/MeshBase";
import topFloorGLB from "./topFloor.glb?url";
import { degToRad } from "three/src/math/MathUtils";
import PlaneWithHtml from "three-base/PlaneWithHtml";
import WindowGroup from "../WindowGroup/WindowGroup";
import { BuildWindowData, WindowData, WindowTypeData } from "@views/home/type";
import FloorNum from "./FloorNum/FloorNum";
import Text3D from "three-base/Text3D";
import indicatorGLB from "../GLTF/indicator.glb?url";
import config from "@views/home/config/config";
import { vector } from "echarts";
import window1GLB from "./window1.glb?url";
import window2GLB from "./window2.glb?url";

// 设置字体文件的请求地址
Text3D.path = "//www.3dkeshihua.com/three-base-font/";

// 楼房
export default class Building extends Group {

    constructor() {
        super();
    }

    // 1楼 带大门
    oneFloor = (() => {
        const oneFloor = new OneFloor();
        oneFloor.position.set(0, 0.6, 0,);
        this.add(oneFloor);
        return oneFloor;
    })();

    //楼层组
    floorGroup = (() => {
        const floorGroup = new FloorGroup();
        floorGroup.position.set(-0.067, 0.15, 0);
        this.add(floorGroup);
        return floorGroup;
    })();

    // -1楼数字
    num_1 = (() => {
        const num_1 = new Text3D("-1");
        num_1.rotation.set(0, degToRad(90), 0);
        num_1.position.set(1.151, 0, -1.264);
        num_1.setText({
            size: 0.2,
            height: 0.001, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.02, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        num_1.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0,
            roughness: 0.3
        });
        this.add(num_1);
        return num_1;
    })();

    // -2楼数字
    num_2 = (() => {
        const num_2 = new Text3D("-2");
        num_2.rotation.set(0, degToRad(90), 0);
        num_2.position.set(1.151, 0.3, -1.264);
        num_2.setText({
            size: 0.2,
            height: 0.001, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.02, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        num_2.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0,
            roughness: 0.3
        });
        this.add(num_2);
        return num_2;
    })();

    // 楼层号
    floorNum = (() => {
        const floorNum = new FloorNum();
        floorNum.rotation.set(0, degToRad(90), 0);
        floorNum.position.set(1.151, 0, -1.264);
        this.add(floorNum);
        return floorNum;
    })();

    // 顶楼广告牌
    topFloor = (() => {
        const topFloor = new MeshBase(topFloorGLB);
        topFloor.addEventListener("loaded", () => {
            const originPosition = topFloor.position.clone();
            topFloor.rotateY(degToRad(-90));
            threeUtils.scaleTo(topFloor, 0.8, ["y"]);
            threeUtils.center(topFloor);
            threeUtils.alignBottom(topFloor);
            // const adMap = threeLoader.getTexture(adPNG);
            // adMap.flipY = false;
            // topFloor.traverseMesh(mesh => {
            //     if (["平面001"].includes(mesh.name)) {
            //         (mesh as Mesh).material = new MeshBasicMaterial({ map: adMap });
            //     }
            // });
            topFloor.position.copy(originPosition);
            this.add(topFloor);
        });

        return topFloor;
    })();

    // 指示器
    indicator = (() => {
        const indicator = new MeshBase(indicatorGLB);
        indicator.position.set(0, 0, 0);
        // keyContorls.addEventListener("change", e => {
        //     //@ts-ignore
        //     indicator.position.add(e.direction);
        //     console.log(indicator.position.toArray().map(v => round(v, 3)).join(", "));
        // });
        indicator.addEventListener("loaded", () => {
            threeUtils.scaleTo(indicator, 1);
            indicator.scale.setY(0.01);
            indicator.traverseMesh(m => {
                m.material.color.set("#ffffff");
                m.material.roughness = 0.5;
                m.material.metalness = 0.3;
            })
        });
        this.add(indicator);
        return indicator;
    })();

    // 楼号
    planeWithHtml = (() => {
        const planeWithHtml = new PlaneWithHtml(`
            <span style="font-family: 黑体;font-size:80px;color:#000;display:inline-block;width: 340px;height: 200px;border: 0px solid #ffffff;border-radius: 50%;text-align: center;line-height: 80px;" >1栋</span>
        `);

        planeWithHtml.scale.set(0.002, 0.002, 0.002);
        planeWithHtml.rotateX(degToRad(90));
        planeWithHtml.rotateZ(degToRad(-90));

        this.add(planeWithHtml);
        return planeWithHtml;
    })();

    //东
    east = (() => {
        const east = new Text3D("东");
        east.rotation.set(0, degToRad(180), 0);
        east.position.set(0, 0.3, -1.12);
        east.setText({
            size: 0.2,
            height: 0.01, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.2, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        east.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0.3,
            roughness: 0.5
        });
        this.add(east);
        return east;
    })();

    //南字
    south = (() => {
        const south = new Text3D("南");
        south.rotation.set(0, degToRad(90), 0);
        south.position.set(1.13, 0.3, 0);
        south.setText({
            size: 0.2,
            height: 0.01, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.2, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        south.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0.3,
            roughness: 0.5
        });
        this.add(south);
        return south;
    })();

    // 西
    west = (() => {
        const west = new Text3D("西");
        west.rotation.set(0, degToRad(0), 0);
        west.position.set(0, 0.3, 1.12);
        west.setText({
            size: 0.2,
            height: 0.01, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.2, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        west.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0.3,
            roughness: 0.5
        });
        this.add(west);
        return west;
    })();

    // 北
    north = (() => {
        const north = new Text3D("北");
        north.rotation.set(0, degToRad(-90), 0);
        north.position.set(-1.265, 0.3, 0);
        north.setText({
            size: 0.2,
            height: 0.01, // 文字的厚度
            bevelEnabled: false, // 斜角开启
            bevelThickness: 0.2, // 斜角厚度
            bevelSize: 0.015, // 斜角大小
            bevelOffset: 0,// 斜角偏移
            bevelSegments: 3,//斜角分段
        });
        north.material = new MeshStandardMaterial({
            color: "#00fbff",
            metalness: 0.3,
            roughness: 0.5
        });
        this.add(north);
        return north;
    })();


    //窗户组
    windowGroup = (() => {
        const windowGroup = new WindowGroup();
        windowGroup.position.set(-0.067, 0, 0);
        this.add(windowGroup);
        return windowGroup;
    })();

    // 楼层号
    buildNo = "0";

    // 等待加载完成
    async awaitLoaded() {
        while (!this.oneFloor.loaded || !this.topFloor.loaded || !this.floorGroup.loaded) {
            await new Promise(resolve => setTimeout(resolve, 50));
        }
    }

    // 设置楼号
    setBuildNo(num: string) {
        this.buildNo = num;
        this.planeWithHtml.setHtml(`
            <span style="font-family: 黑体;font-size:80px;color:#000;display:inline-block;width: 340px;height: 200px;border: 0px solid #ffffff;border-radius: 50%;text-align: center;line-height: 80px;" >${num}</span>
        `);
        this.planeWithHtml.scale.set(0.002, 0.002, 0.002);
    }

    async setData(buildWindowData: Array<BuildWindowData>, windowType: Array<WindowTypeData>) {
        const { floorHeight } = homeStore;
        let maxWindow = { // 东南2个方向最大的窗户数量
            east: Math.max(0,
                ...buildWindowData.map(b => {
                    return Math.max(0,
                        get(b, ["east", "num"]),
                        get(b, ["west", "num"]),

                    );
                })
            ),
            south: Math.max(0,
                ...buildWindowData.map(b => {
                    return Math.max(0,
                        get(b, ["north", "num"]),
                        get(b, ["south", "num"]),
                    );
                })
            )
        };

        // 窗户数据
        const windowDatas: Array<WindowData> = [];
        // 更具窗户的数量计算东南2个网格的偏移量

        const offset = {
            east: (8 - Math.max(5, maxWindow.east)) * 0.14,
            south: (8 - Math.max(5, maxWindow.south)) * 0.14,
        };

        //窗户的类型
        buildWindowData.map((b, floor) => {
            const east = get(b, ["east", "num"]) || 0; // 东
            const west = get(b, ["west", "num"]) || 0; // 西

            const north = get(b, ["north", "num"]) || 0; // 北
            const south = get(b, ["south", "num"]) || 0; // 南

            const south_kuang = get(b, ["south", "mdDisp_kuang"]) || 0; // 南面的框安装数量
            const south_saifeng = get(b, ["south", "mdDisp_saifeng"]) || 0; // 南面的塞缝
            const south_shan = get(b, ["south", "mdDisp_shan"]) || 0; // 南面的扇/五金
            const south_boli = get(b, ["south", "mdDisp_boli"]) || 0; // 南面的玻璃
            const south_mifj = get(b, ["south", "mdDisp_mifj"]) || 0; // 南面的密封胶

            const { winList } = windowType[floor];

            // const name = get(b, ["name"]) || "";
            // const url = get(b, ["url"]) || "";

            // 南面的窗户
            for (let i = 0; i < south; i++) {
                const windowData = {
                    name: "",
                    url: window1GLB,
                    color: "#ffffff",
                    installState: "",
                    installColor: "#ffffff",
                    position: new Vector3(1.195 - offset.east, floorHeight * (floor + 2.5), i * 0.25 - ((south - 1) * 0.125)),
                    rotation: new Euler(0, degToRad(90), 0),
                }

                //配置南面各窗户的颜色
                if (i < south_kuang) {
                    Object.assign(windowData, config.installState.find(c => c.key === "kuang"));
                } else if (i < (south_kuang + south_saifeng)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "saifeng"));
                } else if (i < (south_kuang + south_saifeng + south_shan)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "shan"));
                } else if (i < (south_kuang + south_saifeng + south_shan + south_boli)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "boli"));
                } else if (i < (south_kuang + south_saifeng + south_shan + south_boli + south_mifj)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "mifj"));
                }

                //设置窗户的类型和颜色
                let windowIndex = i;
                for (let ii = 0; ii < winList.length; ii++) {
                    if (windowIndex < winList[ii].south) {
                        Object.assign(windowData, {
                            name: winList[ii].name,
                            color: winList[ii].color
                        });
                        break;
                    } else {
                        windowIndex -= winList[ii].south;
                    }
                }

                windowDatas.push(windowData);
            }

            const north_kuang = get(b, ["north", "mdDisp_kuang"]) || 0; // 北面的框安装数量
            const north_saifeng = get(b, ["north", "mdDisp_saifeng"]) || 0; // 北面的塞缝
            const north_shan = get(b, ["north", "mdDisp_shan"]) || 0; // 北面的扇/五金
            const north_boli = get(b, ["north", "mdDisp_boli"]) || 0; // 北面的玻璃
            const north_mifj = get(b, ["north", "mdDisp_mifj"]) || 0; // 北面的密封胶

            // 北面的窗户
            for (let i = 0; i < north; i++) {
                const windowData = {
                    name: "",
                    url: window1GLB,
                    color: "#ffffff",
                    installState: "",
                    installColor: "#ffffff",
                    position: new Vector3(-1.195 + offset.east, floorHeight * (floor + 2.5), i * 0.25 - ((north - 1) * 0.125)),
                    rotation: new Euler(0, degToRad(90), 0),
                };

                //配置北面各窗户的颜色
                if (i < north_kuang) {
                    Object.assign(windowData, config.installState.find(c => c.key === "kuang"));
                } else if (i < (north_kuang + north_saifeng)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "saifeng"));
                } else if (i < (north_kuang + north_saifeng + north_shan)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "shan"));
                } else if (i < (north_kuang + north_saifeng + north_shan + north_boli)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "boli"));
                } else if (i < (north_kuang + north_saifeng + north_shan + north_boli + north_mifj)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "mifj"));
                }

                //设置窗户的类型和颜色
                let windowIndex = i;
                for (let ii = 0; ii < winList.length; ii++) {
                    if (windowIndex < winList[ii].north) {
                        Object.assign(windowData, {
                            name: winList[ii].name,
                            color: winList[ii].color
                        });
                        break;
                    } else {
                        windowIndex -= winList[ii].north;
                    }
                }

                windowDatas.push(windowData);
            }

            const west_kuang = get(b, ["west", "mdDisp_kuang"]) || 0; // 西面的框安装数量
            const west_saifeng = get(b, ["west", "mdDisp_saifeng"]) || 0; // 西面的塞缝
            const west_shan = get(b, ["west", "mdDisp_shan"]) || 0; // 西面的扇/五金
            const west_boli = get(b, ["west", "mdDisp_boli"]) || 0; // 西面的玻璃
            const west_mifj = get(b, ["west", "mdDisp_mifj"]) || 0; // 西面的密封胶

            // 西面的窗户
            for (let i = 0; i < west; i++) {
                const windowData = {
                    name: "",
                    url: window2GLB,
                    color: "#ffffff",
                    installState: "",
                    installColor: "#ffffff",
                    position: new Vector3(i * 0.25 - ((west - 1) * 0.125), floorHeight * (floor + 2.5), 1.12 - offset.south),
                    rotation: new Euler(0, degToRad(0), 0),
                };

                //配置西面各窗户的颜色
                if (i < west_kuang) {
                    Object.assign(windowData, config.installState.find(c => c.key === "kuang"));
                } else if (i < (west_kuang + west_saifeng)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "saifeng"));
                } else if (i < (west_kuang + west_saifeng + west_shan)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "shan"));
                } else if (i < (west_kuang + west_saifeng + west_shan + west_boli)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "boli"));
                } else if (i < (west_kuang + west_saifeng + west_shan + west_boli + west_mifj)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "mifj"));
                }

                //设置窗户的类型和颜色
                let windowIndex = i;
                for (let ii = 0; ii < winList.length; ii++) {
                    if (windowIndex < winList[ii].west) {
                        Object.assign(windowData, {
                            name: winList[ii].name,
                            color: winList[ii].color
                        });
                        break;
                    } else {
                        windowIndex -= winList[ii].west;
                    }
                }

                windowDatas.push(windowData);
            }

            const east_kuang = get(b, ["east", "mdDisp_kuang"]) || 0; // 东面的框安装数量
            const east_saifeng = get(b, ["east", "mdDisp_saifeng"]) || 0; // 东面的塞缝
            const east_shan = get(b, ["east", "mdDisp_shan"]) || 0; // 东面的扇/五金
            const east_boli = get(b, ["east", "mdDisp_boli"]) || 0; // 东面的玻璃
            const east_mifj = get(b, ["east", "mdDisp_mifj"]) || 0; // 东面的密封胶

            // 东面的窗户
            for (let i = 0; i < east; i++) {
                const windowData = {
                    name: "",
                    url: window2GLB,
                    color: "#FFFFff",
                    installState: "",
                    installColor: "#ffffff",
                    position: new Vector3(i * 0.25 - ((east - 1) * 0.125), floorHeight * (floor + 2.5), -1.12 + offset.south),
                    rotation: new Euler(0, degToRad(180), 0),
                };

                //配置东面各窗户的颜色
                if (i < east_kuang) {
                    Object.assign(windowData, config.installState.find(c => c.key === "kuang"));
                } else if (i < (east_kuang + east_saifeng)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "saifeng"));
                } else if (i < (east_kuang + east_saifeng + east_shan)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "shan"));
                } else if (i < (east_kuang + east_saifeng + east_shan + east_boli)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "boli"));
                } else if (i < (east_kuang + east_saifeng + east_shan + east_boli + east_mifj)) {
                    Object.assign(windowData, config.installState.find(c => c.key === "mifj"));
                }

                //设置窗户的类型和颜色
                let windowIndex = i;
                for (let ii = 0; ii < winList.length; ii++) {
                    if (windowIndex < winList[ii].east) {
                        Object.assign(windowData, {
                            name: winList[ii].name,
                            color: winList[ii].color
                        });
                        break;
                    } else {
                        windowIndex -= winList[ii].east;
                    }
                }

                windowDatas.push(windowData);
            }

        });

        const floorNum = buildWindowData.length;

        this.oneFloor.setWindowNum(maxWindow);

        this.floorGroup.setFloorNum(floorNum, maxWindow);

        // 楼层号
        this.floorNum.setFloorNum(floorNum);
        this.floorNum.position.set(1.151 - offset.east, 0, -1.264 + offset.south);

        //-1楼数字
        this.num_1.position.set(1.151 - offset.east, 0, -1.264 + offset.south);
        //-2楼数字
        this.num_2.position.set(1.151 - offset.east, 0.3, -1.264 + offset.south);

        //顶楼的广告牌
        this.topFloor.position.set(1.14 - offset.east, 0.25 + ((floorNum + 4) * floorHeight), 0);
        //东字
        this.east.position.set(0, 0.28 + ((floorNum + 2) * floorHeight), -1.12 + offset.south);
        //南字
        this.south.position.set(1.13 - offset.east, 0.28 + ((floorNum + 2) * floorHeight), 0);
        // 西
        this.west.position.set(0, 0.28 + ((floorNum + 2) * floorHeight), 1.12 - offset.south);
        // 北
        this.north.position.set(-1.265 + offset.east, 0.28 + ((floorNum + 2) * floorHeight), 0);

        this.indicator.position.set(0, 0.25 + ((floorNum + 2) * floorHeight), 0);
        this.planeWithHtml.position.set(1.15 - offset.east, 1.15 + ((floorNum + 1) * floorHeight), 0);
        await this.windowGroup.setData(floorNum, maxWindow, windowDatas);
    }



}